/*
 * ListenerManager.java
 *
 * Created on December 7, 2006, 7:32 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.umn.cs5115.scheduler.framework;

/**
 * Generic class for sending notifications to your custom listener interface.
 * @author grant
 */
public class ListenerManager<T>
{
    /** Listeners */
    private IteratorSafeSet<T> listeners = new IteratorSafeSet();
    /** Default notifier; used in notifyListeners() */
    private Notifier<T> defaultNotifier;
    
    /** Creates a new instance of ListenerManager */
    public ListenerManager()
    {
        this(null);
    }
    
    /** 
     * Creates a new instance of ListenerManager with a given default notifier.
     * @param defaultNotifier The default Notifier to use when calling notify 
     * without a notifier.
     */
    public ListenerManager(Notifier<T> defaultNotifier)
    {
        this.setDefaultNotifier(defaultNotifier);
    }
    
    /**
     * Adds a listener to the list of listeners to notify.
     * @param listener The listener to add
     */
    public void addListener(T listener)
    {
        listeners.add(listener);
    }
    
    /**
     * Removes a listener from the list of listeners to notify.
     * @param listener The listener to remove.
     */
    public void removeListener(Object listener)
    {
        listeners.remove(listener);
    }
    
    /**
     * Notifies all your listeners using your custom notifier, set using 
     * setDefaultNotifier()
     * @see #notifyListeners(Notifier)
     */
    public void notifyListeners()
    {
        notifyListeners(getDefaultNotifier());
    }
    
    /**
     * Notifies all of the listeners using the given notifier.
     */
    public void notifyListeners(Notifier<T> notifier)
    {
        if (notifier != null)
        {
            listeners.startIterating();
            for(T listener : listeners)
                notifier.notifyListener(listener);
            listeners.finishIterating();
        }
    }

    /**
     * Gets the default notifier.  This is used when you call notifyListeners().
     * @return The current default notifier.
     * @see #notifyListeners()
     */
    public Notifier<T> getDefaultNotifier()
    {
        return defaultNotifier;
    }

    /**
     * Sets the default notifier.  This is used when you call notifyListeners().
     * @param defaultNotifier The new default notifier to use.
     * @see #notifyListeners()
     */
    public void setDefaultNotifier(Notifier<T> defaultNotifier)
    {
        this.defaultNotifier = defaultNotifier;
    }
    
    /** Notification interface for notifying listeners. */
    public static interface Notifier<T>
    {
        /** Notify the given listener. */
        public void notifyListener(T object);
    }
}
